#include "rtsp_server.h"
#include <iostream>
#include <thread>
#include <chrono>
#include <cstdio>
#include <cstring>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <unistd.h>

RTSPServer::RTSPServer(int port) 
    : m_port(port), 
      m_isRunning(false), 
      m_scheduler(nullptr), 
      m_environment(nullptr), 
      m_rtspServer(nullptr) {
}

RTSPServer::~RTSPServer() {
    stop();
    
    if (m_rtspServer) {
        Medium::close(m_rtspServer);
        m_rtspServer = nullptr;
    }
    
    if (m_environment) {
        delete m_environment;
        m_environment = nullptr;
    }
    
    if (m_scheduler) {
        delete m_scheduler;
        m_scheduler = nullptr;
    }
}

bool RTSPServer::start() {
    if (m_isRunning) {
        std::cout << "RTSP服务器已经在运行中" << std::endl;
        return true;
    }
    
    // 创建任务调度器和使用环境
    m_scheduler = BasicTaskScheduler::createNew();
    if (!m_scheduler) {
        std::cerr << "创建任务调度器失败" << std::endl;
        return false;
    }
    
    m_environment = BasicUsageEnvironment::createNew(*m_scheduler);
    if (!m_environment) {
        std::cerr << "创建使用环境失败" << std::endl;
        delete m_scheduler;
        m_scheduler = nullptr;
        return false;
    }
    
    // 创建RTSP服务器
    if (!createServer()) {
        std::cerr << "创建RTSP服务器失败" << std::endl;
        delete m_environment;
        delete m_scheduler;
        m_environment = nullptr;
        m_scheduler = nullptr;
        return false;
    }
    
    // 启动事件循环线程
    m_isRunning = true;
    m_eventLoopThread = std::thread(eventLoopThread, this);
    
    std::cout << "RTSP服务器启动成功，监听端口: " << m_port << std::endl;
    std::cout << "服务器URL: " << getServerUrl() << std::endl;
    
    return true;
}

void RTSPServer::stop() {
    if (!m_isRunning) {
        return;
    }
    
    m_isRunning = false;
    
    // 中断事件循环
    if (m_scheduler) {
        m_scheduler->doEventLoop(&m_isRunning);
    }
    
    // 等待事件循环线程结束
    if (m_eventLoopThread.joinable()) {
        m_eventLoopThread.join();
    }
    
    std::cout << "RTSP服务器已停止" << std::endl;
}

bool RTSPServer::createServer() {
    if (!m_environment || !m_scheduler) {
        return false;
    }
    
    // 创建RTSP服务器实例
    m_rtspServer = ::RTSPServer::createNew(*m_environment, m_port);
    if (!m_rtspServer) {
        *m_environment << "创建RTSP服务器失败: " << m_environment->getResultMsg() << "\n";
        return false;
    }
    
    return true;
}

bool RTSPServer::addH264Stream(const char* streamName, const char* filePath) {
    if (!m_isRunning || !m_rtspServer || !m_environment) {
        std::cerr << "服务器未运行或无效的环境" << std::endl;
        return false;
    }
    
    // 检查文件是否存在
    FILE* file = fopen(filePath, "rb");
    if (!file) {
        std::cerr << "无法打开H264文件: " << filePath << std::endl;
        return false;
    }
    fclose(file);
    
    // 创建媒体会话
    ServerMediaSession* sms = createServerMediaSession(streamName, "H.264 Video Stream");
    if (!sms) {
        return false;
    }
    
    // 添加H264子会话
    ServerMediaSubsession* subsession = createH264ServerMediaSubsession(*m_environment, filePath, true);
    if (!subsession) {
        Medium::close(sms);
        return false;
    }
    
    sms->addSubsession(subsession);
    
    // 将媒体会话添加到服务器
    m_rtspServer->addServerMediaSession(sms);
    
    // 打印流URL
    char* url = m_rtspServer->rtspURL(sms);
    *m_environment << "添加H264流成功: " << url << "\n";
    delete[] url;
    
    return true;
}

bool RTSPServer::addH265Stream(const char* streamName, const char* filePath) {
    if (!m_isRunning || !m_rtspServer || !m_environment) {
        std::cerr << "服务器未运行或无效的环境" << std::endl;
        return false;
    }
    
    // 检查文件是否存在
    FILE* file = fopen(filePath, "rb");
    if (!file) {
        std::cerr << "无法打开H265文件: " << filePath << std::endl;
        return false;
    }
    fclose(file);
    
    // 创建媒体会话
    ServerMediaSession* sms = createServerMediaSession(streamName, "H.265 Video Stream");
    if (!sms) {
        return false;
    }
    
    // 添加H265子会话
    ServerMediaSubsession* subsession = createH265ServerMediaSubsession(*m_environment, filePath, true);
    if (!subsession) {
        Medium::close(sms);
        return false;
    }
    
    sms->addSubsession(subsession);
    
    // 将媒体会话添加到服务器
    m_rtspServer->addServerMediaSession(sms);
    
    // 打印流URL
    char* url = m_rtspServer->rtspURL(sms);
    *m_environment << "添加H265流成功: " << url << "\n";
    delete[] url;
    
    return true;
}

bool RTSPServer::addMJPEGStream(const char* streamName, const char* filePath) {
    if (!m_isRunning || !m_rtspServer || !m_environment) {
        std::cerr << "服务器未运行或无效的环境" << std::endl;
        return false;
    }
    
    // 检查文件是否存在
    FILE* file = fopen(filePath, "rb");
    if (!file) {
        std::cerr << "无法打开MJPEG文件: " << filePath << std::endl;
        return false;
    }
    fclose(file);
    
    // 创建媒体会话
    ServerMediaSession* sms = createServerMediaSession(streamName, "MJPEG Video Stream");
    if (!sms) {
        return false;
    }
    
    // 添加MJPEG子会话
    ServerMediaSubsession* subsession = createMJPEGServerMediaSubsession(*m_environment, filePath, true);
    if (!subsession) {
        Medium::close(sms);
        return false;
    }
    
    sms->addSubsession(subsession);
    
    // 将媒体会话添加到服务器
    m_rtspServer->addServerMediaSession(sms);
    
    // 打印流URL
    char* url = m_rtspServer->rtspURL(sms);
    *m_environment << "添加MJPEG流成功: " << url << "\n";
    delete[] url;
    
    return true;
}

ServerMediaSession* RTSPServer::createServerMediaSession(const char* streamName, const char* description) {
    if (!m_environment) {
        return nullptr;
    }
    
    // 创建服务器媒体会话
    ServerMediaSession* sms = ServerMediaSession::createNew(*m_environment, streamName, streamName, description);
    if (!sms) {
        *m_environment << "创建媒体会话失败" << "\n";
        return nullptr;
    }
    
    return sms;
}

ServerMediaSubsession* RTSPServer::createH264ServerMediaSubsession(UsageEnvironment& env, const char* filePath, bool reuseFirstSource) {
    // 创建H264文件源
    H264VideoFileServerMediaSubsession* subsession = H264VideoFileServerMediaSubsession::createNew(env, filePath, reuseFirstSource);
    if (!subsession) {
        env << "创建H264子会话失败" << "\n";
        return nullptr;
    }
    
    return subsession;
}

ServerMediaSubsession* RTSPServer::createH265ServerMediaSubsession(UsageEnvironment& env, const char* filePath, bool reuseFirstSource) {
    // 创建H265文件源
    H265VideoFileServerMediaSubsession* subsession = H265VideoFileServerMediaSubsession::createNew(env, filePath, reuseFirstSource);
    if (!subsession) {
        env << "创建H265子会话失败" << "\n";
        return nullptr;
    }
    
    return subsession;
}

ServerMediaSubsession* RTSPServer::createMJPEGServerMediaSubsession(UsageEnvironment& env, const char* filePath, bool reuseFirstSource) {
    // 创建MJPEG文件源
    MJPEGVideoFileServerMediaSubsession* subsession = MJPEGVideoFileServerMediaSubsession::createNew(env, filePath, reuseFirstSource);
    if (!subsession) {
        env << "创建MJPEG子会话失败" << "\n";
        return nullptr;
    }
    
    return subsession;
}

void RTSPServer::eventLoopThread(void* data) {
    RTSPServer* server = static_cast<RTSPServer*>(data);
    if (server && server->m_scheduler && server->m_environment) {
        server->m_scheduler->doEventLoop(&server->m_isRunning);
    }
}

std::string RTSPServer::getServerUrl() const {
    if (!m_rtspServer) {
        return "";
    }
    
    // 获取服务器的IP地址
    struct sockaddr_in sa;
    int len = sizeof(sa);
    getsockname(m_rtspServer->tcpSocketNum(), (struct sockaddr*)&sa, &len);
    char ip[INET_ADDRSTRLEN];
    inet_ntop(AF_INET, &(sa.sin_addr), ip, INET_ADDRSTRLEN);
    
    // 构建服务器URL
    std::string url = "rtsp://";
    url += ip;
    url += ":";
    url += std::to_string(m_port);
    url += "/";
    
    return url;
}